package com.example.service.impl;

import com.example.common.Result;
import com.example.dto.SystemConfigDTO;
import com.example.entity.SystemConfig;
import com.example.mapper.SystemConfigMapper;
import com.example.service.SystemConfigService;
import com.example.vo.SystemConfigVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 系统配置服务实现类
 */
@Slf4j
@Service
public class SystemConfigServiceImpl implements SystemConfigService {
    
    @Autowired
    private SystemConfigMapper systemConfigMapper;
    
    @PostConstruct
    public void init() {
        initDefaultConfigs();
    }
    
    @Override
    public Result<List<SystemConfigVO>> getAllConfigs() {
        try {
            List<SystemConfig> configs = systemConfigMapper.selectAll();
            List<SystemConfigVO> configVOs = configs.stream()
                    .map(this::convertToVO)
                    .collect(Collectors.toList());
            return Result.success(configVOs);
        } catch (Exception e) {
            log.error("获取所有配置失败", e);
            return Result.error("获取配置失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<List<SystemConfigVO>> getConfigsByGroup(String group) {
        try {
            List<SystemConfig> configs = systemConfigMapper.selectByGroup(group);
            List<SystemConfigVO> configVOs = configs.stream()
                    .map(this::convertToVO)
                    .collect(Collectors.toList());
            return Result.success(configVOs);
        } catch (Exception e) {
            log.error("根据分组获取配置失败: group={}", group, e);
            return Result.error("获取配置失败：" + e.getMessage());
        }
    }
    
    @Override
    public String getConfigValue(String configKey) {
        return getConfigValue(configKey, null);
    }
    
    @Override
    public String getConfigValue(String configKey, String defaultValue) {
        try {
            SystemConfig config = systemConfigMapper.selectByKey(configKey);
            return config != null ? config.getConfigValue() : defaultValue;
        } catch (Exception e) {
            log.error("获取配置值失败: configKey={}", configKey, e);
            return defaultValue;
        }
    }
    
    @Override
    public boolean getBooleanConfig(String configKey, boolean defaultValue) {
        String value = getConfigValue(configKey);
        if (value == null) {
            return defaultValue;
        }
        return "true".equalsIgnoreCase(value) || "1".equals(value);
    }
    
    @Override
    public int getIntConfig(String configKey, int defaultValue) {
        String value = getConfigValue(configKey);
        if (value == null) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }
    
    @Override
    public Result<SystemConfigVO> getConfigById(Long id) {
        try {
            SystemConfig config = systemConfigMapper.selectById(id);
            if (config == null) {
                return Result.error("配置不存在");
            }
            return Result.success(convertToVO(config));
        } catch (Exception e) {
            log.error("根据ID获取配置失败: id={}", id, e);
            return Result.error("获取配置失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> addConfig(SystemConfigDTO configDTO) {
        try {
            // 检查配置键是否已存在
            if (systemConfigMapper.countByKey(configDTO.getConfigKey()) > 0) {
                return Result.error("配置键已存在");
            }
            
            SystemConfig config = convertToEntity(configDTO);
            config.setCreateTime(LocalDateTime.now());
            config.setUpdateTime(LocalDateTime.now());
            config.setDeleted(0);
            
            systemConfigMapper.insert(config);
            return Result.success();
        } catch (Exception e) {
            log.error("新增配置失败", e);
            return Result.error("新增配置失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> updateConfig(Long id, SystemConfigDTO configDTO) {
        try {
            SystemConfig existingConfig = systemConfigMapper.selectById(id);
            if (existingConfig == null) {
                return Result.error("配置不存在");
            }
            
            // 检查配置键是否与其他配置冲突
            SystemConfig configWithSameKey = systemConfigMapper.selectByKey(configDTO.getConfigKey());
            if (configWithSameKey != null && !configWithSameKey.getId().equals(id)) {
                return Result.error("配置键已存在");
            }
            
            SystemConfig config = convertToEntity(configDTO);
            config.setId(id);
            config.setUpdateTime(LocalDateTime.now());
            
            systemConfigMapper.updateById(config);
            return Result.success();
        } catch (Exception e) {
            log.error("更新配置失败: id={}", id, e);
            return Result.error("更新配置失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> updateConfigValue(String configKey, String configValue) {
        try {
            systemConfigMapper.updateValueByKey(configKey, configValue, LocalDateTime.now());
            return Result.success();
        } catch (Exception e) {
            log.error("更新配置值失败: configKey={}", configKey, e);
            return Result.error("更新配置值失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> batchUpdateConfigs(Map<String, String> configs) {
        try {
            for (Map.Entry<String, String> entry : configs.entrySet()) {
                systemConfigMapper.updateValueByKey(entry.getKey(), entry.getValue(), LocalDateTime.now());
            }
            return Result.success();
        } catch (Exception e) {
            log.error("批量更新配置失败", e);
            return Result.error("批量更新配置失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> deleteConfig(Long id) {
        try {
            SystemConfig config = systemConfigMapper.selectById(id);
            if (config == null) {
                return Result.error("配置不存在");
            }
            
            // 系统内置配置不允许删除
            if (config.getIsSystem() != null && config.getIsSystem() == 1) {
                return Result.error("系统内置配置不允许删除");
            }
            
            systemConfigMapper.deleteById(id, LocalDateTime.now());
            return Result.success();
        } catch (Exception e) {
            log.error("删除配置失败: id={}", id, e);
            return Result.error("删除配置失败：" + e.getMessage());
        }
    }
    
    @Override
    public void initDefaultConfigs() {
        try {
            // 邮箱功能配置
            createConfigIfNotExists("email.enabled", "false", "邮箱功能开关", 
                    "是否启用邮箱功能", "BOOLEAN", "EMAIL", 1, 1, 1);
            
            createConfigIfNotExists("email.register.enabled", "false", "邮箱注册开关", 
                    "是否启用邮箱注册功能", "BOOLEAN", "EMAIL", 1, 1, 2);
            
            createConfigIfNotExists("email.login.enabled", "false", "邮箱登录开关", 
                    "是否启用邮箱登录功能", "BOOLEAN", "EMAIL", 1, 1, 3);
            
            createConfigIfNotExists("email.code.expire", "300", "验证码过期时间",
                    "邮箱验证码过期时间（秒）", "NUMBER", "EMAIL", 1, 1, 4);

            // 手机号功能配置
            createConfigIfNotExists("phone.enabled", "false", "手机号功能开关",
                    "是否启用手机号功能", "BOOLEAN", "PHONE", 1, 1, 1);

            createConfigIfNotExists("phone.register.enabled", "false", "手机号注册开关",
                    "是否启用手机号注册功能", "BOOLEAN", "PHONE", 1, 1, 2);

            createConfigIfNotExists("phone.login.enabled", "false", "手机号登录开关",
                    "是否启用手机号登录功能", "BOOLEAN", "PHONE", 1, 1, 3);

            createConfigIfNotExists("phone.code.expire", "300", "短信验证码过期时间",
                    "手机号验证码过期时间（秒）", "NUMBER", "PHONE", 1, 1, 4);

            // 验证码功能配置
            createConfigIfNotExists("captcha.enabled", "true", "验证码功能开关",
                    "是否启用登录验证码功能", "BOOLEAN", "CAPTCHA", 1, 1, 1);

            createConfigIfNotExists("captcha.login.enabled", "true", "登录验证码开关",
                    "账号密码登录是否需要验证码", "BOOLEAN", "CAPTCHA", 1, 1, 2);

            createConfigIfNotExists("captcha.register.enabled", "false", "注册验证码开关",
                    "注册时是否需要验证码", "BOOLEAN", "CAPTCHA", 1, 1, 3);

            createConfigIfNotExists("captcha.type", "image", "验证码类型",
                    "验证码类型：image-图片验证码，slider-滑块验证码，math-数学运算验证码", "STRING", "CAPTCHA", 1, 1, 4);

            createConfigIfNotExists("captcha.expire", "300", "验证码过期时间",
                    "验证码过期时间（秒）", "NUMBER", "CAPTCHA", 1, 1, 5);

            createConfigIfNotExists("captcha.length", "4", "验证码长度",
                    "图片验证码字符长度", "NUMBER", "CAPTCHA", 1, 1, 6);

            createConfigIfNotExists("captcha.width", "120", "验证码宽度",
                    "图片验证码宽度（像素）", "NUMBER", "CAPTCHA", 1, 1, 7);

            createConfigIfNotExists("captcha.height", "40", "验证码高度",
                    "图片验证码高度（像素）", "NUMBER", "CAPTCHA", 1, 1, 8);

            createConfigIfNotExists("captcha.noise.enabled", "true", "验证码干扰线",
                    "是否启用验证码干扰线", "BOOLEAN", "CAPTCHA", 1, 1, 9);

            createConfigIfNotExists("captcha.case.sensitive", "false", "验证码大小写敏感",
                    "验证码是否区分大小写", "BOOLEAN", "CAPTCHA", 1, 1, 10);

            log.info("系统默认配置初始化完成");
        } catch (Exception e) {
            log.error("初始化系统默认配置失败", e);
        }
    }
    
    @Override
    public boolean isEmailEnabled() {
        return getBooleanConfig("email.enabled", false);
    }
    
    @Override
    public boolean isEmailRegisterEnabled() {
        return isEmailEnabled() && getBooleanConfig("email.register.enabled", false);
    }
    
    @Override
    public boolean isEmailLoginEnabled() {
        return isEmailEnabled() && getBooleanConfig("email.login.enabled", false);
    }

    @Override
    public boolean isPhoneEnabled() {
        return getBooleanConfig("phone.enabled", false);
    }

    @Override
    public boolean isPhoneRegisterEnabled() {
        return isPhoneEnabled() && getBooleanConfig("phone.register.enabled", false);
    }

    @Override
    public boolean isPhoneLoginEnabled() {
        return isPhoneEnabled() && getBooleanConfig("phone.login.enabled", false);
    }

    @Override
    public boolean isCaptchaEnabled() {
        return getBooleanConfig("captcha.enabled", false);
    }

    @Override
    public boolean isLoginCaptchaEnabled() {
        return isCaptchaEnabled() && getBooleanConfig("captcha.login.enabled", false);
    }

    @Override
    public boolean isRegisterCaptchaEnabled() {
        return isCaptchaEnabled() && getBooleanConfig("captcha.register.enabled", false);
    }

    /**
     * 创建配置（如果不存在）
     */
    private void createConfigIfNotExists(String configKey, String configValue, String configName,
                                       String description, String configType, String configGroup,
                                       Integer isSystem, Integer status, Integer sort) {
        if (systemConfigMapper.countByKey(configKey) == 0) {
            SystemConfig config = new SystemConfig();
            config.setConfigKey(configKey);
            config.setConfigValue(configValue);
            config.setConfigName(configName);
            config.setDescription(description);
            config.setConfigType(configType);
            config.setConfigGroup(configGroup);
            config.setIsSystem(isSystem);
            config.setStatus(status);
            config.setSort(sort);
            config.setCreateTime(LocalDateTime.now());
            config.setUpdateTime(LocalDateTime.now());
            config.setDeleted(0);
            
            systemConfigMapper.insert(config);
        }
    }
    
    /**
     * 转换为VO
     */
    private SystemConfigVO convertToVO(SystemConfig config) {
        SystemConfigVO vo = new SystemConfigVO();
        BeanUtils.copyProperties(config, vo);
        return vo;
    }
    
    /**
     * 转换为实体
     */
    private SystemConfig convertToEntity(SystemConfigDTO dto) {
        SystemConfig config = new SystemConfig();
        BeanUtils.copyProperties(dto, config);
        return config;
    }
}
